package cc.leap.web.monitor;

import cc.leap.constant.CacheConstants;
import cc.leap.constant.HttpStatus;
import cc.leap.model.AjaxResult;
import cc.leap.model.LoginUser;
import cc.leap.model.TableDataInfo;
import cc.leap.utils.CacheUtils;
import cc.leap.utils.StringUtils;
import cc.leap.web.vo.UserOnlineVo;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Delete;
import org.noear.solon.annotation.Get;
import org.noear.solon.annotation.Mapping;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * SysUserOnlineController
 *
 * @author leap
 * @date 2024/8/20
 */
@Controller
@Mapping("/monitor/online")
public class SysUserOnlineController {

    @SaCheckPermission("monitor:online:list")
    @Get
    @Mapping("/list")
    public TableDataInfo<UserOnlineVo> list(String ipaddr, String userName) {
        List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
        List<UserOnlineVo> userOnlineList = new ArrayList<>();
        for (String key : keys) {
            String token = StringUtils.substringAfterLast(key, ":");
            // 如果已经过期则跳过
            if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < -1) {
                continue;
            }

            LoginUser user = CacheUtils.getCacheObject(CacheConstants.ONLINE_TOKEN_KEY + ":" + token, LoginUser.class);
            if (ObjectUtil.isNull(user) || ObjectUtil.isNull(user.getUser())) {
                continue;
            }
            UserOnlineVo vo = new UserOnlineVo();
            vo.setTokenId(user.getToken());
            vo.setUserName(user.getUsername());
            vo.setIpaddr(user.getIpaddr());
            vo.setLoginLocation(user.getLoginLocation());
            vo.setBrowser(user.getBrowser());
            vo.setOs(user.getOs());
            vo.setLoginTime(user.getLoginTime());
            if (ObjectUtil.isNotNull(user.getUser().getDept())) {
                vo.setDeptName(user.getUser().getDept().getDeptName());
            }
            userOnlineList.add(vo);
        }
        Collections.reverse(userOnlineList);
        userOnlineList.removeAll(Collections.singleton(null));

        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setRows(userOnlineList);
        rspData.setTotal(userOnlineList.size());
        return rspData;
    }

    /**
     * 强退用户
     */
    @SaCheckPermission("monitor:online:forceLogout")
    @Delete
    @Mapping("/{tokenId}")
    public AjaxResult forceLogout(String tokenId) {
        CacheUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + ":" + tokenId);
        StpUtil.kickoutByTokenValue(tokenId);
        return AjaxResult.success();
    }
}
